import {
  DropdownListFuncDef,
  CodeLineForDropdown,
  GetMfOrgLiteResp,
  GetMfLiteListReq,
  GetMfLiteListResp,
  MfOrgLite,
  CompanyLite,
  WmWhLite,
  BfCbLite,
  SimUserInfo,
} from './dropdownlist.d'
import {GetMfOrgLiteReq} from '../defs/mf'
import {AxiosResponse} from 'axios'

// http header中服务器告诉客户端的ETag的key
export const HttpHeaderEtag = 'etag'
// http header中的用于向服务器询问ETag的key
export const HttpHeaderIfNoneMatch = 'if-none-match'

// 保存到localstorage中的key的前缀
export const DropdownEtagKey = 'dropdown-etag:'
// 保存到localstorage中的key的前缀
export const DropdownDataKey = 'dropdown-data:'

// 尝试从localStorage中获取到资源的etag，并返回带 if-none-match 的header
export function getEtagHeaderAndData(apiPath: string, userName?: string): { headers: Record<string, string>, data: string | null } {
  const dropdownEtag = window.localStorage.getItem(DropdownEtagKey + (userName ? userName.toLowerCase() + ':' : '') + apiPath)
  const dropdownData = window.localStorage.getItem(DropdownDataKey + (userName ? userName.toLowerCase() + ':' : '') + apiPath)
  return {headers: {[HttpHeaderIfNoneMatch]: (dropdownEtag && dropdownData) ? dropdownEtag : ''}, data: dropdownData}
}

// 将服务器返回的数据和header写入localstorage中去
export function setEtagHeaderAndData(apiPath: string, resp: AxiosResponse<any, any>, userName?: string) {
  const etag = $f.misc.getStrProp(resp.headers, HttpHeaderEtag)
  if (etag) {
    window.localStorage.setItem(DropdownEtagKey + (userName ? userName.toLowerCase() + ':' : '') + apiPath, $f.misc.getStrProp(resp.headers, HttpHeaderEtag) ?? '')
    window.localStorage.setItem(DropdownDataKey + (userName ? userName.toLowerCase() + ':' : '') + apiPath, JSON.stringify(resp.data))
  }
}

const getCodeForDropdown = function (codeName: string): Promise<CodeLineForDropdown[]> {
  const apiPath = '/comm/code/get-code-for-dropdown/' + codeName
  const localCache = getEtagHeaderAndData(apiPath)
  return $f.axios.get<CodeLineForDropdown[]>(apiPath, {headers: localCache.headers})
    .then(result => {
      setEtagHeaderAndData(apiPath, result)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as CodeLineForDropdown[]
      }
      throw err
    })
}

const getMfSimpleList = function (params: GetMfLiteListReq): Promise<GetMfLiteListResp> {
  const apiPath = '/comm/mf/get-mf-simple-list/'
  let strParams = '' //Mf列表查询的额外参数
  if (params) {
    strParams = JSON.stringify(params)
  }
  const localCache = getEtagHeaderAndData(apiPath + strParams, $f.ua?.value.userName)
  return $f.axios.get<GetMfLiteListResp>(apiPath, {headers: localCache.headers, params: params})
    .then(result => {
      setEtagHeaderAndData(apiPath + strParams, result, $f.ua?.value.userName)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as GetMfLiteListResp
      }
      throw err
    })
}

const getMfOrgSimpleList = function (mfId: number): Promise<MfOrgLite[]> {
  const apiPath = '/comm/mf/get-mf-org-simple-list/' + mfId.toString()
  const localCache = getEtagHeaderAndData(apiPath, $f.ua?.value.userName)
  return $f.axios.get<MfOrgLite[]>(apiPath, {headers: localCache.headers})
    .then(result => {
      setEtagHeaderAndData(apiPath, result, $f.ua?.value.userName)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as MfOrgLite[]
      }
      throw err
    })
}

const getAllMfOrgSimpleList = function (params: GetMfOrgLiteReq): Promise<GetMfOrgLiteResp> {
  const apiPath = '/comm/mf/get-mf-org-simple-list'
  let strParams = '' //MfOrg列表查询的额外参数
  if (params) {

    strParams = JSON.stringify(params)
  }
  const localCache = getEtagHeaderAndData(apiPath + strParams, $f.ua?.value.userName)
  return $f.axios.get<GetMfOrgLiteResp>(apiPath, {headers: localCache.headers, params: params})
    .then(result => {
      setEtagHeaderAndData(apiPath + strParams, result, $f.ua?.value.userName)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as GetMfOrgLiteResp
      }
      throw err
    })
}

const getCompanySimpleList = function (): Promise<CompanyLite[]> {
  const apiPath = '/comm/company/get-company-simple-list/'
  const localCache = getEtagHeaderAndData(apiPath, $f.ua?.value.userName)
  return $f.axios.get<CompanyLite[]>(apiPath, {headers: localCache.headers})
    .then(result => {
      setEtagHeaderAndData(apiPath, result, $f.ua?.value.userName)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as CompanyLite[]
      }
      throw err
    })
}

const getWmWhSimpleList = function (): Promise<WmWhLite[]> {
  console.warn('请在WMS中实现dropdownList的getWmWhSimpleList方法')
  return Promise.resolve([])
}

const getBfCbSimpleList = function (): Promise<BfCbLite[]> {
  console.warn('请在BFS中实现dropdownList的getBfCbSimpleList方法')
  return Promise.resolve([])
}

const getSimUserInfoList = function (includeApiUsers: boolean): Promise<SimUserInfo[]> {
  let apiPath = '/comm/usermgr/get-sim-user-info-list'
  if (includeApiUsers) {
    apiPath += '?includeApiUsers=true'
  }
  const localCache = getEtagHeaderAndData(apiPath)
  return $f.axios.get<SimUserInfo[]>(apiPath, {headers: localCache.headers})
    .then(result => {
      setEtagHeaderAndData(apiPath, result)
      return result.data
    })
    .catch(err => {
      if ($f.getAxiosErrCode(err) === 304) {
        return JSON.parse(localCache.data!) as SimUserInfo[]
      }
      throw err
    })
}


export default {
  getCodeForDropdown,
  getMfSimpleList,
  getMfOrgSimpleList,
  getAllMfOrgSimpleList,
  getCompanySimpleList,
  getWmWhSimpleList,
  getBfCbSimpleList,
  getSimUserInfoList,
} as DropdownListFuncDef
